/*****************************************************************************
 * ui_sys_quick_win.c: Copyright 2023 (c) CoreLink
 * Desc:
 *
 * Author: Flying (weekend@111.com)
 * Date: 2023-09-07 17:56:02
 * Notes:
 *
 * ---------------------------------------------------------------------------
 * LastEditors:
 * LastEditTime:
 *****************************************************************************/
/*------------------------------- Includes ----------------------------------*/
#include "ui_sys_quick_win.h"

/*------------------- 全局定义和声明 -------------------*/

/*---------------------- 常量/宏定义 -----------------------*/

/*----------------------- 类型声明 ---------------------------------*/

/*----------------------- 变量声明 -----------------------------*/

/*----------------------- 函数原型 --------------------------------*/
static void ui_sys_quick_win_exit_evnet_cb(lv_event_t *e);
static void ui_sys_quick_win_open_changer_anim_cb(void *var, int32_t v);
static void ui_sys_quick_win_calc_end_pos(ui_sys_quick_win_info_t *info);
static void ui_sys_quick_win_exit_changer_anim_cb(void *var, int32_t v);
/*----------------------- 功能实现 --------------------------------*/
ui_sys_quick_win_info_t *ui_sys_quick_win_create(int start_x, int start_y, sys_quick_func_t func)
{
    ui_sys_quick_win_info_t *info = (ui_sys_quick_win_info_t *)MY_MALLOC(sizeof(ui_sys_quick_win_info_t));
    memset(info, 0, sizeof(ui_sys_quick_win_info_t));
    info->start_x = start_x;
    info->start_y = start_y;
    info->end_x = start_x;
    info->end_y = start_y;
    info->is_show = false;

    // LV_LOG_USER("x %d,y %d", start_x, start_y);
    info->cont = lv_obj_create(lv_layer_sys());
    lv_obj_set_style_radius(info->cont, 0, 0);
    lv_obj_set_pos(info->cont, 0, 0);
    lv_obj_set_style_pad_all(info->cont, 0, 0);
    lv_obj_set_size(info->cont, lv_pct(100), lv_pct(100));
    lv_obj_set_style_opa(info->cont, LV_OPA_10, 0);
    lv_obj_set_style_bg_color(info->cont, lv_color_black(), 0);
    lv_obj_set_style_border_width(info->cont, 0, 0);

    lv_obj_add_event_cb(info->cont, ui_sys_quick_win_exit_evnet_cb, LV_EVENT_CLICKED, info);

    LV_ASSERT(func);

    info->win = func(lv_layer_sys());
    lv_obj_set_pos(info->win, start_x, start_y);
    lv_obj_set_user_data(info->win, info);
    info->w = lv_obj_get_style_width(info->win, 0);
    info->h = lv_obj_get_style_height(info->win, 0);

    for (int i = 0; i < lv_obj_get_child_cnt(info->win); i++)
    {
        lv_obj_add_flag(lv_obj_get_child(info->win, i), LV_OBJ_FLAG_HIDDEN);
    }

    // info->win = lv_obj_create(info->cont);
    // lv_obj_set_style_bg_color(info->win, lv_color_black(), 0);
    // lv_obj_set_pos(info->win, start_x, start_y);
    // lv_obj_set_style_pad_all(info->win, 0, 0);
    // lv_obj_set_user_data(info->win, info);

    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, info->win);
    lv_anim_set_exec_cb(&a, ui_sys_quick_win_open_changer_anim_cb);
    lv_anim_set_path_cb(&a, lv_anim_path_ease_in);
    lv_anim_set_values(&a, 0, 300);
    lv_anim_set_time(&a, 300);
    lv_anim_start(&a);

    ui_sys_quick_win_calc_end_pos(info);
    return info;
}
// int ui_sys_quick_win_show(ui_sys_quick_win_info_t *info)
// {
// }
int ui_sys_quick_win_delete(ui_sys_quick_win_info_t *info)
{
    if (lv_anim_get(info->win, ui_sys_quick_win_exit_changer_anim_cb))
    {
        return -1;
    }
    for (int i = 0; i < lv_obj_get_child_cnt(info->win); i++)
    {
        lv_obj_add_flag(lv_obj_get_child(info->win, i), LV_OBJ_FLAG_HIDDEN);
    }

    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, info->win);
    lv_anim_set_exec_cb(&a, ui_sys_quick_win_exit_changer_anim_cb);
    lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
    lv_anim_set_values(&a, 0, 300);
    lv_anim_set_time(&a, 300);
    lv_anim_start(&a);
    return 0;
}

static void ui_sys_quick_win_exit_evnet_cb(lv_event_t *e)
{
    ui_sys_quick_win_info_t *info = (ui_sys_quick_win_info_t *)lv_event_get_user_data(e);
    if (info->is_show == false)
    {
        return;
    }

    ui_sys_quick_win_delete(info);
}

/**
 * @description: 动画轨迹
 * @param {void} *var
 * @param {int32_t} v
 * @return {*}
 */
static void ui_sys_quick_win_open_changer_anim_cb(void *var, int32_t v)
{
    lv_obj_t *obj = (lv_obj_t *)var;
    lv_coord_t w, h;
    lv_coord_t x, y;
    ui_sys_quick_win_info_t *info = (ui_sys_quick_win_info_t *)lv_obj_get_user_data(obj);

    x = lv_map(v, 0, 300, info->start_x, info->end_x);
    y = lv_map(v, 0, 300, info->start_y, info->end_y);
    w = lv_map(v, 0, 300, 0, info->w);
    h = lv_map(v, 0, 300, 0, info->h);
    lv_obj_set_pos(obj, x, y);
    lv_obj_set_size(obj, w, h);
    if (v == 300)
    {
        info->is_show = true;
        for (int i = 0; i < lv_obj_get_child_cnt(info->win); i++)
        {
            lv_obj_clear_flag(lv_obj_get_child(info->win, i), LV_OBJ_FLAG_HIDDEN);
        }
    }
}

/**
 * @description: 退出动画轨迹
 * @param {void} *var
 * @param {int32_t} v
 * @return {*}
 */
static void ui_sys_quick_win_exit_changer_anim_cb(void *var, int32_t v)
{
    lv_obj_t *obj = (lv_obj_t *)var;
    lv_coord_t w, h;
    lv_coord_t x, y;
    ui_sys_quick_win_info_t *info = (ui_sys_quick_win_info_t *)lv_obj_get_user_data(obj);

    x = lv_map(v, 0, 300, info->end_x, info->start_x);
    y = lv_map(v, 0, 300, info->end_y, info->start_y);
    w = lv_map(v, 0, 300, info->w, 0);
    h = lv_map(v, 0, 300, info->h, 0);
    lv_obj_set_pos(obj, x, y);
    lv_obj_set_size(obj, w, h);
    if (v == 300)
    {
        lv_obj_del_async(info->cont);
        info->cont = NULL;
        lv_obj_del_async(info->win);
        info->win = NULL;
        MY_FREE(info);
    }
}
/**
 * @description: 计算终点坐标
 * @return {*}
 */
static void ui_sys_quick_win_calc_end_pos(ui_sys_quick_win_info_t *info)
{
    if (info->start_y + info->h < MY_UI_H_MAX)
    { // 向下
        info->end_y = info->start_y;
        if (info->start_x + info->w < MY_UI_W_MAX)
        { // 左边
            info->end_x = info->start_x;
            return;
        }

        if (info->start_x - info->w >= 0)
        { // 右边
            info->end_x = info->start_x - info->w;
            return;
        }
    }

    if (info->start_y - info->h >= 0)
    { // 向上
        info->end_y = info->start_y - info->h;

        if (info->start_x + info->w < MY_UI_W_MAX)
        { // 左边
            info->end_x = info->start_x;
            return;
        }

        if (info->start_x - info->w >= 0)
        { // 右边
            info->end_x = info->start_x - info->w;
            return;
        }
    }

    // 其余情况居中，并预留退出空间
    info->w = info->w > MY_UI_W_MAX - 50 * MY_UI_W_ZOOM ? MY_UI_W_MAX - 50 * MY_UI_W_ZOOM : info->w;
    info->h = info->h > MY_UI_H_MAX - 50 * MY_UI_W_ZOOM ? MY_UI_H_MAX - 50 * MY_UI_H_ZOOM : info->h;
    info->end_x = (MY_UI_W_MAX - info->w) / 2;
    info->end_y = (MY_UI_H_MAX - info->h) / 2;
}
/*---------------------------------------------------------------------------*/